package getUrls

import (
	"bufio"
	"fmt"
	"io"
	"os"

	"SearchEngine/analysis/ac"
)

var (
	code = make(chan string, 1) // 放入从doc_raw.bin读取的源代码
)

// 从已下载的doc_raw.bin文件中，筛选出url，并添加到urls.bin文件中
func getUrls() {
	//1.构建AC自动机
	acAutoMachine := ac.NewAcAutoMachine()
	acAutoMachine.AddPattern(`href="http`)
	acAutoMachine.Build()
	//2.打开doc_raw.bin文件，读取要筛选的内容
	go readFile()
	// 不断读取、筛选源代码，存储
	for {
		//3.获得目标字符串起始位置
		content, ok := <-code
		if !ok {
			fmt.Println("doc_raw.bin文件中的URL已全部筛选完毕")
			break
		}
		urls := make([]string, 0)
		_, startIndexs := acAutoMachine.Search(content)
		//4.获得全部目标url字符串
		for _, startIndex := range startIndexs {
			len := 0
			for _, r := range []rune(content)[startIndex+6:] {
				if r == '"' {
					break
				}
				len++
			}
			urls = append(urls, string([]rune(content)[startIndex+6:startIndex+6+len]))
		}

		//5.存储并写入到urls.bin文件中
		urlFileName := "/home/fcou/go/src/SearchEngine/collect/urls/urls.bin"
		SaveUrlsTofile(urlFileName, urls)
	}
}

// 读取待爬取网页,获取源代码，放入通道code中
func readFile() {
	fmt.Println("开始读取doc_raw.bin文件")
	defer func() {
		fmt.Println("终止读取doc_raw.bin文件")

	}()
	file, err := os.Open("/home/fcou/go/src/SearchEngine/collect/docRaw/doc_raw.bin")
	if err != nil {
		fmt.Println("file open error:", err)
		return
	}
	defer file.Close()
	defer close(code)

	reader := bufio.NewReader(file)

	buf := make([]byte, 4096)
	for {
		_, err := reader.Read(buf) //每4KB读取一次
		if err == io.EOF {
			fmt.Println("error:", err)
			return
		}
		if err != nil {
			fmt.Println("error:", err)
			return
		}
		code <- string(buf) // 相当于url生产端
	}
}

// 将筛选出的url添加到urls.bin文件中
func SaveUrlsTofile(filmName string, urls []string) {
	f, err := os.OpenFile(filmName, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
	if err != nil {
		fmt.Println("SaveUrlsTofile:", err)
		return
	}
	defer f.Close()
	//使用 bufio.NewWriter 写入文件
	w := bufio.NewWriter(f)
	fmt.Println("开始保存筛选到的url信息到文件")
	//先写入网页编号
	for _, s := range urls {
		w.WriteString(s + "\n")
	}
	w.Flush()
}
